<?php
namespace Base;
use Enums\Code;
use JetBrains\PhpStorm\NoReturn;
use Request;
use Upload;
use Yaf\Controller_Abstract;
use Yaf\Dispatcher;
use Yaf\Exception;

/**
 * 基类控制器
 * Class BaseController
 */
class BaseController extends Controller_Abstract
{
    /**
     * 规则验证类
     * @var ?string
     */
    protected ?string $validate = "";

    /**
     * 初始化
     * @return void
     */
    #[NoReturn] public function init(): void
    {
        if ($this->validate) {
            $this->getRequest()->setParam("YafValidate", $this->validate);
        }
    }

    /**
     * Ajax方式返回数据到客户端
     *
     * @access protected
     * @param array $data 要返回的数据
     * @param String $type AJAX返回数据格式
     * @param int $json_option 传递给json_encode的option参数
     * @return void
     */
    #[NoReturn] protected function ajaxReturn(array $data, string $type = 'JSON', int $json_option = 0): void
    {
        ajaxReturn($data, $type, $json_option);
    }

    /**
     * 接口错误输出
     * @param string $msg 提示信息
     * @param int|null $status 状态
     * @param array $data 需要返回的数据
     * @return void
     */
    #[NoReturn] protected function apiError(string $msg, ?int $status = null, array $data = []): void
    {
        $return = [
            'code' => $status ?: Code::ERROR->value,
            'message' => $msg,
            'data' => $data
        ];
        $this->ajaxReturn($return);
    }

    /**
     * 接口成功输出
     * @param array $data 需要返回的数据
     * @param string $msg 提示信息
     * @param int|null $status 状态
     * @return void
     */
    #[NoReturn] protected function apiSuccess(array $data = [], string $msg = 'success', ?int $status = null): void
    {
        $return = [
            'code' => $status ?: Code::SUCCESS->value,
            'message' => $msg,
            'data' => $data
        ];
        $this->ajaxReturn($return);
    }

    /**
     * 生成接口签名
     * @return string
     */
    #[NoReturn] protected function apiCreateSign(): string
    {
        $secretKey = Dispatcher::getInstance()->getApplication()->getConfig()->get("key.secretKey");
        $data = Request::all();
        unset($data['sign']);
        ksort($data);
        $params = http_build_query($data);
        return md5(urldecode($params) . $secretKey);
    }

    /**
     * 后台验证sign是否合法
     * @return void
     */
    #[NoReturn] protected function verifySign(): void {
        $data = Request::all();
        /** 验证参数中是否有签名 */
        if (!isset($data['signature']) || !$data['signature']) $this->apiError('发送的数据签名不存在');
        if (!isset($data['timestamp']) || !$data['timestamp']) $this->apiError('发送的数据参数不合法');
        /** 验证请求， 10分钟失效 */
        if (time() - $data['timestamp'] > 600)$this->apiError('验证失效， 请重新发送请求');
        if ($data['sign'] != $this->apiCreateSign()) {
            $this->apiError('请求不合法');
        }
    }

    /**
     * 文件上传公共方法
     * @return void
     */
    #[NoReturn] public function uploadAction():void
    {
        if (Request::instance()->isPost()) {
            $config = [
                'maxSize' => 4145728,
                'exts' => 'jpg,gif,png,jpeg,mp4,svga',
                'rootPath' => './public/uploads/fileTemp/',
                'saveName' => 'uniqid',
                'autoSub'=>false,
            ];
            try {
                if (!is_dir($config['rootPath'])) mkdir($config['rootPath'], 0755, true);
                $uploadInfo = Upload::upload();
                if (!$uploadInfo) $this->apiError(Upload::getError());
            } catch (Exception $e) {
                $this->apiError($e->getMessage());
            }
            if(isset($uploadInfo['file'])) {
                $url = getRequestHost(). "/" . $config['rootPath'] . $uploadInfo['file']['savepath'] . $uploadInfo['file']['savename'];
            }else {
                $url = [];
                foreach($uploadInfo as $vo){
                    $url[] = getRequestHost(). "/" . $config['rootPath'] . $vo['savepath'] .$vo['savename'];
                }
            }
            $this->apiSuccess(['url'=>$url],"上传成功",20000);
        }
    }
}
